<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" charset="utf-8">
        /**
         * 鸭式辨型法
         * 优点：完全面向对象，代码也统一了，也解耦了
         * 一个类实现接口的主要目的，把接口里的方法都实现
         */
        /**
         *
         * @param name 接口的名字
         * @param methods 接收方法的名称的集合（数组）
         */
        var Interface = function (name,methods) {
            //判断接口参数的个数
            if(arguments.length!=2){
                throw new Error('this instance constructor arguments must be 2 length!');

            }
            this.name = name;
            this.methods = [];
            for (var i = 0,len = methods.length;i<len;i++){
                if(typeof methods[i]!=='string'){
                    throw new Error('the interface method name is error!');
                }
                this.methods.push(methods[i]);
            }
        }
        //实例化接口对象
        var CompositeInterface = new Interface('CompositeInterface',['add','remove']);
        var FormItemInterface = new Interface('FormItemInterface',['update','select']);
        var CompsiteImpl = function () {
        }
        CompsiteImpl.prototype.add = function (obj) {
            alert('add...');
        }
        CompsiteImpl.prototype.remove = function (obj) {
            alert('remove...');
        }
        CompsiteImpl.prototype.update = function (obj) {
            alert('update...');

        }

        /*CompsiteImpl.prototype.select = function (obj) {
            alert('select...');
        }*/
        //检验接口里的方法
        Interface.ensureImplements = function (object) {
            if(arguments.length<2){
                throw new Error('Interface.ensureImplements method constructor arguments must be>=2!');
            }
            //获得接口实例对象
            for(var i = 1,len=arguments.length;i<len;i++){
                var instanceInterface = arguments[i];
                //判断参数是否是接口类型
                if(instanceInterface.constructor!==Interface){
                    throw new Error('the arguments constructor not be Interface class ');
                }
                //循环接口实例对象中的每一个方法
                for(var j = 0;j<instanceInterface.methods.length;j++){
                    var methodName = instanceInterface.methods[j];
                    if(!object[methodName] || typeof object[methodName]!=='function'){
                        throw new Error("the method name "+methodName+" is not found");
                    }
                }
            }
        }
        var c1 = new CompsiteImpl();
        Interface.ensureImplements(c1,CompositeInterface,FormItemInterface);
        c1.add();
    </script>
</head>
<body>
</body>
</html>